/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package au.com.gworks.jump.app.wiki.server;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.javaongems.runtime.lang.StringUtils;
import org.javaongems.server.EntryPointPage;
import org.javaongems.server.GemEntryPointPager;
import org.javaongems.server.PrincipalUtils;

import au.com.gworks.jump.app.util.EnvironmentUtils;
import au.com.gworks.jump.app.util.RequestPathInfo;
import au.com.gworks.jump.app.wiki.client.service.WikiRpc;
import au.com.gworks.jump.io.ResourceAttributes;
import au.com.gworks.jump.io.ResourceNotFound;
import au.com.gworks.jump.io.SystemFailure;
import au.com.gworks.jump.io.UnauthorisedAccess;
import au.com.gworks.jump.tool.CompilerError;

import com.google.gwt.user.client.rpc.SerializableException;

abstract public class WikiEntryPointPage extends EntryPointPage {
	final static private Logger LOGGER = Logger.getLogger(WikiEntryPointPage.class);
	protected RequestPathInfo requestPathInfo;
	
	protected void onRenderRedirectIfRequired() throws IOException {
		Boolean wasNamespaceSpecified = (Boolean) request.getAttribute(EnvironmentUtils.ENV_WAS_NAMESPACE_SPECIFIED);
		requestPathInfo = (RequestPathInfo) request.getAttribute(EnvironmentUtils.ENV_REQUEST_PATH_INFO_OBJ);
		if (!wasNamespaceSpecified.booleanValue()) {
			String uri = requestPathInfo.getOrigRevisionContext(false);
			String qs = request.getQueryString();
			if (!StringUtils.isEmpty(qs))
				uri += "?" + qs; 
			EnvironmentUtils.redirectToSubContextUri(response, uri);
		}
	}

	protected void registerGemProperties() {
		Map props = getGemProperties();
		HttpServletRequest req = getRequest();
		props.put("contextType", new Integer(getContextId()));
		props.put("isAuthenticated", req.getAttribute(EnvironmentUtils.ENV_REQUEST_ISAUTHENTICATED));
		props.put("isHeadRevision", new Boolean(requestPathInfo.isHeadRevision()));
		props.put("jump.wiki.subctx", EnvironmentUtils.getApplicationSubcontext("wiki-param", false).substring(1));
		String revDocCtx = (String) req.getAttribute(EnvironmentUtils.ENV_REV_DOC_CTX);
		props.put("revDocCtx",revDocCtx);
		props.put("toggleUriWithQs", req.getAttribute(EnvironmentUtils.ENV_REQUEST_TOGGLE_URI_WITH_QS));
		props.put("userName", PrincipalUtils.getPrincipal(req).getName());
		
		props.put("requestPathInfo.baselineRevision", requestPathInfo.makeBaseRevisionContext());
		props.put("requestPathInfo.context", requestPathInfo.context);
		props.put("requestPathInfo.namespace", requestPathInfo.namespace);
		props.put("requestPathInfo.path", requestPathInfo.path);
		props.put("requestPathInfo.pathStatus", new Integer(requestPathInfo.pathStatus));
		props.put("requestPathInfo.revSpecifier", requestPathInfo.revSpecifier);
		props.put("requestPathInfo.headRevision", requestPathInfo.headRevision);
		props.put("requestPathInfo.isNamespaceAdmin", new Boolean(requestPathInfo.isNamespaceAdmin));
		props.put("requestPathInfo.revision", requestPathInfo.revision);
		props.put("requestPathInfo.wasRevisionSpecified", new Boolean(requestPathInfo.wasRevisionSpecified));
		
		props.put("requestPathInfo.ra.lastModified", new Long(requestPathInfo.attributes.getLastModified()));
		props.put("requestPathInfo.ra.lastUpdater", requestPathInfo.attributes.getLastUpdater());
		props.put("requestPathInfo.ra.name", requestPathInfo.attributes.getName());
		props.put("requestPathInfo.ra.parentPath", requestPathInfo.attributes.getParentPath());
		props.put("requestPathInfo.ra.size", new Long(requestPathInfo.attributes.getSize()));
		props.put("requestPathInfo.ra.uuid", requestPathInfo.attributes.getUuid());
		props.put("requestPathInfo.ra.lastChangedRevision", requestPathInfo.attributes.getLastChangedRevision());
		props.put("requestPathInfo.ra.properties", requestPathInfo.attributes.getProperties().toString());
		props.put("requestPathInfo.ra.revision", requestPathInfo.attributes.getRevision());
		
		Map cargo = getCargo();
		cargo.put("page.title", "Jump - " + revDocCtx);
		cargo.put("page.css", getApplicationContext() +  "jump.css");
		if (LOGGER.isDebugEnabled()) LOGGER.debug(props);
	}
	
	protected SerializableException recastAsSerializableException(Exception err) {
		SerializableException casted = null;
		if (err instanceof UnauthorisedAccess) {
			UnauthorisedAccess error = (UnauthorisedAccess) err;
			casted = new WikiRpc.UnauthorisedAccessException(error
					.getMessage(), error.getUnauthorisedPath());
		} else if (err instanceof ResourceNotFound) {
			ResourceNotFound error = (ResourceNotFound) err;
			casted = new WikiRpc.ResourceNotFoundException(error
					.getMessage(), error.getInvalidPath(), error
					.getRevision(), error.getParentPath(),
					GemEntryPointPager.stackTraceAsString(error.getCause()));
		} else if (err instanceof CompilerError) {
			CompilerError error = (CompilerError) err;
			ResourceAttributes ra = error.getResourceAttributes();
			WikiRpc.ResourceAttrInfo rai = AbstractBeanMapper.map(ra);
			casted = new WikiRpc.CompilationException(error.getMessage(),
					rai, GemEntryPointPager.stackTraceAsString(error.getCause()));
		} else {
			Throwable rootCause = err;
			if (err instanceof SystemFailure)
				err = ((SystemFailure) err).getRootCause();
			casted = new WikiRpc.SystemFailureException(err.getMessage(),
					GemEntryPointPager.stackTraceAsString(rootCause));
		}
		return casted;
	}
	
	abstract protected int getContextId();
}
